package cn.fintecher.pangolin.service.dataimp.task;

import cn.fintecher.pangolin.common.enums.ImportDataExcelStatus;
import cn.fintecher.pangolin.common.enums.ImportTemplateType;
import cn.fintecher.pangolin.common.enums.MessageType;
import cn.fintecher.pangolin.common.exception.BadRequestException;
import cn.fintecher.pangolin.common.model.UserModel;
import cn.fintecher.pangolin.common.utils.SaxParseExcelUtil;
import cn.fintecher.pangolin.entity.elastic.DataImportRecord;
import cn.fintecher.pangolin.entity.elastic.ImportTemplate;
import cn.fintecher.pangolin.entity.elastic.ImportTemplateItem;
import cn.fintecher.pangolin.entity.elastic.PersonalImportModel;
import cn.fintecher.pangolin.service.dataimp.elastic.DataImportRecordElastic;
import cn.fintecher.pangolin.service.dataimp.elastic.PersonalImportModelElastic;
import cn.fintecher.pangolin.service.dataimp.model.ImportModel;
import cn.fintecher.pangolin.service.dataimp.service.BaseService;
import cn.fintecher.pangolin.common.utils.RepositoryUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.InputStream;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * @Auther: xiaqun
 * @Description:
 * @Date: 11:08 2019/9/30
 */

@Service("importCaseUpdateTask")
public class ImportCaseUpdateTask {
    private static final Logger log = LoggerFactory.getLogger(ImportCaseUpdateTask.class);

    @Autowired
    private BaseService baseService;

    @Autowired
    private DataImportRecordElastic dataImportRecordElastic;

    @Autowired
    private PersonalImportModelElastic personalImportModelElastic;

    @Autowired
    private ImportCaseUpdateFuture importCaseUpdateFuture;

    /**
     * 案件更新
     */
    @Async
    @Transactional
    public void updateCase(InputStream inputStream, ImportTemplate importTemplate, DataImportRecord record, String batchNumber, UserModel userModel) {
        //创建任务集合
        List<CompletableFuture<List<ImportModel>>> list = new ArrayList<>();
        Map<Integer, List<Map<String, String>>> dataMap;
        int total = 0;
        try {
            dataMap = SaxParseExcelUtil.parseExcel(inputStream, importTemplate.getTitleStartRow(), importTemplate.getDataStartCol(), -1, importTemplate.getSheetNumber());
            List<ImportTemplateItem> items = importTemplate.getItems();
            Map<String, ImportTemplateItem> map = baseService.processItem(items, importTemplate.getSheetNumber());
            if (map.isEmpty()) { //配置项为空
                record.setStatus(ImportDataExcelStatus.IMPORT_FAILED);
                String fileId = baseService.generateTxt(Collections.singletonList("模板配置项为空"), batchNumber);
                record.setFileId(fileId);
            } else { //配置项不为空
                //验证配置项
                String msg = baseService.validItem(map, ImportTemplateType.CASE_UPDATE);
                if (Objects.nonNull(msg)) { //配置项有误
                    record.setStatus(ImportDataExcelStatus.IMPORT_FAILED);
                    String fileId = baseService.generateTxt(Collections.singletonList(msg), batchNumber);
                    record.setFileId(fileId);
                } else { //配置项无误
                    for (Map.Entry<Integer, List<Map<String, String>>> sheetData : dataMap.entrySet()) {
                        Integer sheetIndex = sheetData.getKey();
                        List<Map<String, String>> sheetDataList = sheetData.getValue();
                        Map<String, String> titleMap = sheetDataList.get(0);
                        sheetDataList.remove(titleMap);
                        total += sheetDataList.size();
                        if (sheetDataList.size() < 1) {
                            throw new BadRequestException(null, "importExcelData", "importExcelData.is.fail");
                        }
                        //分页解析Excel中的数据对象,一页1000条
                        int pageSize = 1000;
                        int pageNumber = (int) Math.ceil((double) sheetDataList.size() / (double) pageSize);
                        for (int i = 0; i < pageNumber; i++) {
                            List<Map<String, String>> mapList = sheetDataList.stream().skip(i * pageSize).limit(pageSize).collect(Collectors.toList());
                            CompletableFuture<List<ImportModel>> task = importCaseUpdateFuture.processExcel(mapList, sheetIndex, batchNumber, map, i * pageSize, record, importTemplate, titleMap);
                            list.add(task);
                        }
                    }
                    List<ImportModel> models = new ArrayList<>();
                    for (CompletableFuture<List<ImportModel>> listCompletableFuture : list) {
                        models.addAll(listCompletableFuture.get());
                    }
                    //处理excel错误
                    List<String> errors = new ArrayList<>();
                    List<PersonalImportModel> personalImportModels = new ArrayList<>();
                    for (ImportModel model : models) {
                        personalImportModels.add(model.getPersonalImportModel());
                        errors.addAll(model.getErrors());
                    }
                    if (!errors.isEmpty()) {
                        record.setStatus(ImportDataExcelStatus.IMPORT_FAILED);
                        String fileId = baseService.generateTxt(errors, batchNumber);
                        record.setFileId(fileId);
                    } else {
                        RepositoryUtil.saveData(personalImportModelElastic, personalImportModels);
                        record.setTotalNumber(total);
                        record.setStatus(ImportDataExcelStatus.IMPORT_SUCCESSFULLY);
                    }
                }
            }
            dataImportRecordElastic.save(record);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            record.setStatus(ImportDataExcelStatus.IMPORT_FAILED);
            String fileId = baseService.generateTxt(Collections.singletonList("案件模板有误"), Long.toString(new Date().getTime()));
            record.setFileId(fileId);
            dataImportRecordElastic.save(record);
        } finally {
            baseService.sendMsg(MessageType.IMPORT_UPDATE_CASE, userModel);
        }
    }
}
